
typedef unsigned uint;

struct Bar
{
  typedef int ThisType;

};

int d = 0;

//SFINAE
template <typename T>
void Foo(char f[sizeof(T::ThisType)])
{
  d |= 4;
}

template <typename T>
void Foo(...)
{
  d |= 2;
}


struct Brain
{
  template <typename T>
  struct Lobe
  {
    static int* Get()
    {
      return NULL;
    }
  };
};




int gDerpyHerpyFerpy = 42;

template <>
struct Brain::Lobe<char>
{
  static int* Get();
};


int* Brain::Lobe<char>::Get()
{
  return &gDerpyHerpyFerpy;
}

// DeclareEnum MovementMode Air, Ground, Hover, Water


template <typename T>
struct EnumWrapper
{
  typedef typename T::Enum EnumType;
  typedef EnumWrapper<T> ThisType;

  EnumType Value;

  EnumWrapper()
  {
    Value = (EnumType)0;
  }

  ThisType& operator=(EnumType value)
  {
    this->Value = value;
    return *this;
  }

  operator EnumType()
  {
    return this->Value;
  }
};

template <typename T>
struct FlagsWrapper
{
  typedef typename T::Enum EnumType;
  typedef FlagsWrapper<T> ThisType;

  EnumType Value;

  FlagsWrapper()
  {
    Value = (EnumType)0;
  }

  ThisType& operator=(EnumType value)
  {
    this->Value = value;
    return *this;
  }

  operator EnumType()
  {
    return this->Value;
  }

  void Set(EnumType flags)
  {
    this->Value = static_cast<EnumType>(static_cast<uint>(this->Value) | static_cast<uint>(flags));
  }

  void Clear(EnumType flags)
  {
    this->Value = static_cast<EnumType>(static_cast<uint>(this->Value) & ~static_cast<uint>(flags));
  }

  void Toggle(EnumType flags)
  {
    this->Value = static_cast<EnumType>(static_cast<uint>(this->Value) ^ static_cast<uint>(flags));
  }

  bool IsSet(EnumType flags)
  {
    return (this->Value & flags) != 0;
  }

  void ClearAll()
  {
    this->Value = 0;
  }
};

struct MovementModes
{
  enum Enum
  {
    Air,
    Ground,
    Hover,
    Water
  };
};

typedef EnumWrapper<MovementModes> MovementMode;



struct PhysicsStates
{
  enum Enum
  {
    Dynamic = 1,
    RotationLocked = 2,
    PositionLocked = 4,
    SendsMessages = 8
  };
};

typedef FlagsWrapper<PhysicsStates> PhysicsState;


struct Ai
{
  void Move(int steps);

  int Move(int x, int y);

  float Herpy(int derpy)
  {
    return derpy * 3.02f;
  }
  
  static void Pikash1()
  {
  }

  void Pikash2()
  {
  }
};


float SomeFunction(int a)
{
  return a * 3.3f;
}

template <typename Return, typename Arg1, Return (*TheActualCompileTimeFunctionPointer) (Arg1)>
void DoStuff(Return (*ForInferringOnly)(Arg1))
{

}

typedef void(*Derp)(int);


void TestBedRun()
{
  //DoStuff(SomeFunction);

  MovementMode mode;
  mode = MovementModes::Ground;

  if (mode == mode)
  {
  }

  if (mode == MovementModes::Ground)
  {
  }

  if (MovementModes::Ground == mode)
  {
  }

  if (mode != mode)
  {
  }

  if (mode != MovementModes::Ground)
  {
  }

  if (MovementModes::Ground != mode)
  {
  }

  PhysicsState state;
  state.Set(PhysicsStates::PositionLocked);
  state.Set(PhysicsStates::SendsMessages);


  state.Toggle(PhysicsStates::Dynamic);

  bool sm = state.IsSet(PhysicsStates::RotationLocked);

  Foo<Bar>("test");
}